package com.waps;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.view.View;
import android.view.ViewGroup;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
 * Created by IntelliJ IDEA.
 * User: guang
 * Date: 11-3-27
 * Time: 下午7:01
 * To change this template use File | Settings | File Templates.
 */
public class DisplayAd {

        private ConnectTask connectTask = null;
        private static DisplayAdNotifier displayAdNotifier;
        private static AppURLConnection appURLConnection = null;

        private Context context;

        private String clickURL = "";
        private String baseURL = "";
        private String urlParams = "";

        private static String adClickURL;
        Bitmap bitmapImage;
        View adView;

        static final String DISPLAY_AD_URL_PATH = "display/ad?";
        final String DISPLAY_AD = "Display Ad";


        public DisplayAd(Context ctx)
        {
            context = ctx;
            appURLConnection = new AppURLConnection();
        }

        public void getDisplayAdDataFromServer(String urlBase, String params, DisplayAdNotifier notifier)
        {
            baseURL = urlBase;
            clickURL = baseURL + DISPLAY_AD_URL_PATH;
            urlParams = params;

            displayAdNotifier = notifier;

            connectTask = new ConnectTask();
            connectTask.execute();
        }


        private class ConnectTask extends AsyncTask<Void, Void, Boolean>
        {
            @Override
            protected Boolean doInBackground(Void... params)
            {
                boolean returnValue = false;
                String response = appURLConnection.connectToURL(clickURL, urlParams);
                if (response == null || response.length() == 0)
                {
                    AppLog.w("ConnectTask","网络错误");
                    displayAdNotifier.getDisplayAdResponseFailed("网络错误.");
                }
                else
                {
                    returnValue = buildResponse(response);
                    if (returnValue == false){
                        AppLog.w("ConnectTask","无法显示广告内容");
                        displayAdNotifier.getDisplayAdResponseFailed("无法显示广告内容.");
                    }
                }
                return returnValue;
            }
        }

        private boolean buildResponse(String response)
        {
            boolean retValue = false;

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder;

            try
            {
                InputStream is = new ByteArrayInputStream(response.getBytes("UTF-8"));

                documentBuilder = factory.newDocumentBuilder();
                Document document = documentBuilder.parse(is);

                adClickURL = getNodeTrimValue(document.getElementsByTagName("ClickUrl"));
                String image_data = getNodeTrimValue(document.getElementsByTagName("Image"));

                decodeBase64(image_data.getBytes(), 0, image_data.getBytes().length);
                bitmapImage = BitmapFactory.decodeByteArray(buffer, 0, pos);

                AppLog.i(DISPLAY_AD, "image: " + bitmapImage.getWidth() + "x" + bitmapImage.getHeight());
                adView = new View(context);
                ViewGroup.LayoutParams layout = new ViewGroup.LayoutParams(bitmapImage.getWidth(), bitmapImage.getHeight());
                adView.setLayoutParams(layout);
                adView.setBackgroundDrawable(new BitmapDrawable(bitmapImage));
                adView.setOnClickListener(new View.OnClickListener()
                {
                    public void onClick(View v)
                    {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(adClickURL));
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        context.startActivity(intent);
                    }
                });

                displayAdNotifier.getDisplayAdResponse(adView);
                retValue = true;
            }
            catch (Exception e)
            {
                AppLog.e(DISPLAY_AD, "Error parsing XML: " + e.toString());
                e.printStackTrace();
            }

            return retValue;
        }


        private String getNodeTrimValue(NodeList nodeList)
        {
            Element element = (Element) nodeList.item(0);
            String nodeValue = "";
            if (element != null)
            {
                NodeList itemNodeList = element.getChildNodes();

                int length = itemNodeList.getLength();
                for (int i = 0; i < length; i++)
                {
                    Node node = ((Node) itemNodeList.item(i));
                    if (node != null)
                        nodeValue += node.getNodeValue();
                }

                if (nodeValue != null && !nodeValue.equals(""))
                {
                    return nodeValue.trim();
                }
                else
                {
                    return null;
                }
            }
            return null;
        }


        private static final byte PAD = '=';


        private static final byte[] DECODE_TABLE = {
                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54,
                55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
                5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
                24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
                35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
        };


        private static final int MASK_8BITS = 0xff;

        private byte[] buffer;

        private int pos;

        private int modulus;

        private boolean eof;

        private int x;

        void decodeBase64(byte[] in, int inPos, int inAvail)
        {

            buffer = new byte[in.length];
            pos = 0;
            eof = false;
            modulus = 0;

            if (inAvail < 0)
            {
                eof = true;
            }
            for (int i = 0; i < inAvail; i++)
            {

                byte b = in[inPos++];

                if (b == PAD)
                {

                    eof = true;
                    break;
                }
                else
                {
                    if (b >= 0 && b < DECODE_TABLE.length)
                    {
                        int result = DECODE_TABLE[b];
                        if (result >= 0)
                        {
                            modulus = (++modulus) % 4;
                            x = (x << 6) + result;
                            if (modulus == 0)
                            {
                                buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS);
                                buffer[pos++] = (byte) ((x >> 8) & MASK_8BITS);
                                buffer[pos++] = (byte) (x & MASK_8BITS);
                            }
                        }
                    }
                }
            }

            if (eof && modulus != 0)
            {
                x = x << 6;
                switch (modulus)
                {
                    case 2:
                        x = x << 6;
                        buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS);
                        break;
                    case 3:
                        buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS);
                        buffer[pos++] = (byte) ((x >> 8) & MASK_8BITS);
                        break;
                }
            }
        }
    }
